home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / wgdb-42.lha / wgdb-4.2 / gdb / i386-tdep.c < prev    next >
C/C++ Source or Header  |  1992-09-11  |  12KB  |  469 lines

  1. /* Intel 386 target-dependent stuff.
  2.    Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <stdio.h>
  21. #include "defs.h"
  22. #include "param.h"
  23. #include "frame.h"
  24. #include "inferior.h"
  25. #include "gdbcore.h"
  26.  
  27. /* helper functions for tm-i386.h */
  28.  
  29. /* stdio style buffering to minimize calls to ptrace */
  30. static CORE_ADDR codestream_next_addr;
  31. static CORE_ADDR codestream_addr;
  32. static unsigned char codestream_buf[sizeof (int)];
  33. static int codestream_off;
  34. static int codestream_cnt;
  35.  
  36. #define codestream_tell() (codestream_addr + codestream_off)
  37. #define codestream_peek() (codestream_cnt == 0 ? \
  38.                codestream_fill(1): codestream_buf[codestream_off])
  39. #define codestream_get() (codestream_cnt-- == 0 ? \
  40.              codestream_fill(0) : codestream_buf[codestream_off++])
  41.  
  42. static unsigned char 
  43. codestream_fill (peek_flag)
  44. {
  45.   codestream_addr = codestream_next_addr;
  46.   codestream_next_addr += sizeof (int);
  47.   codestream_off = 0;
  48.   codestream_cnt = sizeof (int);
  49.   read_memory (codestream_addr,
  50.            (unsigned char *)codestream_buf,
  51.            sizeof (int));
  52.   
  53.   if (peek_flag)
  54.     return (codestream_peek());
  55.   else
  56.     return (codestream_get());
  57. }
  58.  
  59. static void
  60. codestream_seek (place)
  61. {
  62.   codestream_next_addr = place & -sizeof (int);
  63.   codestream_cnt = 0;
  64.   codestream_fill (1);
  65.   while (codestream_tell() != place)
  66.     codestream_get ();
  67. }
  68.  
  69. static void
  70. codestream_read (buf, count)
  71.      unsigned char *buf;
  72. {
  73.   unsigned char *p;
  74.   int i;
  75.   p = buf;
  76.   for (i = 0; i < count; i++)
  77.     *p++ = codestream_get ();
  78. }
  79.  
  80. /* next instruction is a jump, move to target */
  81. static
  82. i386_follow_jump ()
  83. {
  84.   int long_delta;
  85.   short short_delta;
  86.   char byte_delta;
  87.   int data16;
  88.   int pos;
  89.   
  90.   pos = codestream_tell ();
  91.   
  92.   data16 = 0;
  93.   if (codestream_peek () == 0x66)
  94.     {
  95.       codestream_get ();
  96.       data16 = 1;
  97.     }
  98.   
  99.   switch (codestream_get ())
  100.     {
  101.     case 0xe9:
  102.       /* relative jump: if data16 == 0, disp32, else disp16 */
  103.       if (data16)
  104.     {
  105.       codestream_read ((unsigned char *)&short_delta, 2);
  106.  
  107.       /* include size of jmp inst (including the 0x66 prefix).  */
  108.       pos += short_delta + 4; 
  109.     }
  110.       else
  111.     {
  112.       codestream_read ((unsigned char *)&long_delta, 4);
  113.       pos += long_delta + 5;
  114.     }
  115.       break;
  116.     case 0xeb:
  117.       /* relative jump, disp8 (ignore data16) */
  118.       codestream_read ((unsigned char *)&byte_delta, 1);
  119.       pos += byte_delta + 2;
  120.       break;
  121.     }
  122.   codestream_seek (pos);
  123. }
  124.  
  125. /*
  126.  * find & return amound a local space allocated, and advance codestream to
  127.  * first register push (if any)
  128.  *
  129.  * if entry sequence doesn't make sense, return -1, and leave 
  130.  * codestream pointer random
  131.  */
  132. static long
  133. i386_get_frame_setup (pc)
  134. {
  135.   unsigned char op;
  136.   
  137.   codestream_seek (pc);
  138.   
  139.   i386_follow_jump ();
  140.   
  141.   op = codestream_get ();
  142.   
  143.   if (op == 0x58)        /* popl %eax */
  144.     {
  145.       /*
  146.        * this function must start with
  147.        * 
  148.        *    popl %eax          0x58
  149.        *    xchgl %eax, (%esp)  0x87 0x04 0x24
  150.        * or xchgl %eax, 0(%esp) 0x87 0x44 0x24 0x00
  151.        *
  152.        * (the system 5 compiler puts out the second xchg
  153.        * inst, and the assembler doesn't try to optimize it,
  154.        * so the 'sib' form gets generated)
  155.        * 
  156.        * this sequence is used to get the address of the return
  157.        * buffer for a function that returns a structure
  158.        */
  159.       int pos;
  160.       unsigned char buf[4];
  161.       static unsigned char proto1[3] = { 0x87,0x04,0x24 };
  162.       static unsigned char proto2[4] = { 0x87,0x44,0x24,0x00 };
  163.       pos = codestream_tell ();
  164.       codestream_read (buf, 4);
  165.       if (bcmp (buf, proto1, 3) == 0)
  166.     pos += 3;
  167.       else if (bcmp (buf, proto2, 4) == 0)
  168.     pos += 4;
  169.       
  170.       codestream_seek (pos);
  171.       op = codestream_get (); /* update next opcode */
  172.     }
  173.   
  174.   if (op == 0x55)        /* pushl %ebp */
  175.     {            
  176.       /* check for movl %esp, %ebp - can be written two ways */
  177.       switch (codestream_get ())
  178.     {
  179.     case 0x8b:
  180.       if (codestream_get () != 0xec)
  181.         return (-1);
  182.       break;
  183.     case 0x89:
  184.       if (codestream_get () != 0xe5)
  185.         return (-1);
  186.       break;
  187.     default:
  188.       return (-1);
  189.     }
  190.       /* check for stack adjustment 
  191.        *
  192.        *  subl $XXX, %esp
  193.        *
  194.        * note: you can't subtract a 16 bit immediate
  195.        * from a 32 bit reg, so we don't have to worry
  196.        * about a data16 prefix 
  197.        */
  198.       op = codestream_peek ();
  199.       if (op == 0x83)
  200.     {
  201.       /* subl with 8 bit immed */
  202.       codestream_get ();
  203.       if (codestream_get () != 0xec)
  204.         /* Some instruction starting with 0x83 other than subl.  */
  205.         {
  206.           codestream_seek (codestream_tell () - 2);
  207.           return 0;
  208.         }
  209.       /* subl with signed byte immediate 
  210.        * (though it wouldn't make sense to be negative)
  211.        */
  212.       return (codestream_get());
  213.     }
  214.       else if (op == 0x81)
  215.     {
  216.       /* subl with 32 bit immed */
  217.       int locals;
  218.       codestream_get();
  219.       if (codestream_get () != 0xec)
  220.         /* Some instruction starting with 0x81 other than subl.  */
  221.         {
  222.           codestream_seek (codestream_tell () - 2);
  223.           return 0;
  224.         }
  225.       /* subl with 32 bit immediate */
  226.       codestream_read ((unsigned char *)&locals, 4);
  227.       SWAP_TARGET_AND_HOST (&locals, 4);
  228.       return (locals);
  229.     }
  230.       else
  231.     {
  232.       return (0);
  233.     }
  234.     }
  235.   else if (op == 0xc8)
  236.     {
  237.       /* enter instruction: arg is 16 bit unsigned immed */
  238.       unsigned short slocals;
  239.       codestream_read ((unsigned char *)&slocals, 2);
  240.       SWAP_TARGET_AND_HOST (&slocals, 2);
  241.       codestream_get (); /* flush final byte of enter instruction */
  242.       return (slocals);
  243.     }
  244.   return (-1);
  245. }
  246.  
  247. /* Return number of args passed to a frame.
  248.    Can return -1, meaning no way to tell.  */
  249.  
  250. /* on the 386, the instruction following the call could be:
  251.  *  popl %ecx        -  one arg
  252.  *  addl $imm, %esp  -  imm/4 args; imm may be 8 or 32 bits
  253.  *  anything else    -  zero args
  254.  */
  255.  
  256. int
  257. i386_frame_num_args (fi)
  258.      struct frame_info fi;
  259. {
  260.   int retpc;                        
  261.   unsigned char op;                    
  262.   struct frame_info *pfi;
  263.  
  264.   int frameless;
  265.  
  266.   FRAMELESS_FUNCTION_INVOCATION (fi, frameless);
  267.   if (frameless)
  268.     /* In the absence of a frame pointer, GDB doesn't get correct values
  269.        for nameless arguments.  Return -1, so it doesn't print any
  270.        nameless arguments.  */
  271.     return -1;
  272.  
  273.   pfi = get_prev_frame_info ((fi));            
  274.   if (pfi == 0)
  275.     {
  276.       /* Note:  this can happen if we are looking at the frame for
  277.      main, because FRAME_CHAIN_VALID won't let us go into
  278.      start.  If we have debugging symbols, that's not really
  279.      a big deal; it just means it will only show as many arguments
  280.      to main as are declared.  */
  281.       return -1;
  282.     }
  283.   else
  284.     {
  285.       retpc = pfi->pc;                    
  286.       op = read_memory_integer (retpc, 1);            
  287.       if (op == 0x59)                    
  288.     /* pop %ecx */                   
  289.     return 1;                
  290.       else if (op == 0x83)
  291.     {
  292.       op = read_memory_integer (retpc+1, 1);    
  293.       if (op == 0xc4)                
  294.         /* addl $<signed imm 8 bits>, %esp */    
  295.         return (read_memory_integer (retpc+2,1)&0xff)/4;
  296.       else
  297.         return 0;
  298.     }
  299.       else if (op == 0x81)
  300.     { /* add with 32 bit immediate */
  301.       op = read_memory_integer (retpc+1, 1);    
  302.       if (op == 0xc4)                
  303.         /* addl $<imm 32>, %esp */        
  304.         return read_memory_integer (retpc+2, 4) / 4;
  305.       else
  306.         return 0;
  307.     }
  308.       else
  309.     {
  310.       return 0;
  311.     }
  312.     }
  313. }
  314.  
  315. /*
  316.  * parse the first few instructions of the function to see
  317.  * what registers were stored.
  318.  *
  319.  * We handle these cases:
  320.  *
  321.  * The startup sequence can be at the start of the function,
  322.  * or the function can start with a branch to startup code at the end.
  323.  *
  324.  * %ebp can be set up with either the 'enter' instruction, or 
  325.  * 'pushl %ebp, movl %esp, %ebp' (enter is too slow to be useful,
  326.  * but was once used in the sys5 compiler)
  327.  *
  328.  * Local space is allocated just below the saved %ebp by either the
  329.  * 'enter' instruction, or by 'subl $<size>, %esp'.  'enter' has
  330.  * a 16 bit unsigned argument for space to allocate, and the
  331.  * 'addl' instruction could have either a signed byte, or
  332.  * 32 bit immediate.
  333.  *
  334.  * Next, the registers used by this function are pushed.  In
  335.  * the sys5 compiler they will always be in the order: %edi, %esi, %ebx
  336.  * (and sometimes a harmless bug causes it to also save but not restore %eax);
  337.  * however, the code below is willing to see the pushes in any order,
  338.  * and will handle up to 8 of them.
  339.  *
  340.  * If the setup sequence is at the end of the function, then the
  341.  * next instruction will be a branch back to the start.
  342.  */
  343.  
  344. i386_frame_find_saved_regs (fip, fsrp)
  345.      struct frame_info *fip;
  346.      struct frame_saved_regs *fsrp;
  347. {
  348.   long locals;
  349.   unsigned char *p;
  350.   unsigned char op;
  351.   CORE_ADDR dummy_bottom;
  352.   CORE_ADDR adr;
  353.   int i;
  354.   
  355.   bzero (fsrp, sizeof *fsrp);
  356.   
  357.   /* if frame is the end of a dummy, compute where the
  358.    * beginning would be
  359.    */
  360.   dummy_bottom = fip->frame - 4 - REGISTER_BYTES - CALL_DUMMY_LENGTH;
  361.   
  362.   /* check if the PC is in the stack, in a dummy frame */
  363.   if (dummy_bottom <= fip->pc && fip->pc <= fip->frame) 
  364.     {
  365.       /* all regs were saved by push_call_dummy () */
  366.       adr = fip->frame;
  367.       for (i = 0; i < NUM_REGS; i++) 
  368.     {
  369.       adr -= REGISTER_RAW_SIZE (i);
  370.       fsrp->regs[i] = adr;
  371.     }
  372.       return;
  373.     }
  374.   
  375.   locals = i386_get_frame_setup (get_pc_function_start (fip->pc));
  376.   
  377.   if (locals >= 0) 
  378.     {
  379.       adr = fip->frame - 4 - locals;
  380.       for (i = 0; i < 8; i++) 
  381.     {
  382.       op = codestream_get ();
  383.       if (op < 0x50 || op > 0x57)
  384.         break;
  385.       fsrp->regs[op - 0x50] = adr;
  386.       adr -= 4;
  387.     }
  388.     }
  389.   
  390.   fsrp->regs[PC_REGNUM] = fip->frame + 4;
  391.   fsrp->regs[FP_REGNUM] = fip->frame;
  392. }
  393.  
  394. /* return pc of first real instruction */
  395. i386_skip_prologue (pc)
  396. {
  397.   unsigned char op;
  398.   int i;
  399.   
  400.   if (i386_get_frame_setup (pc) < 0)
  401.     return (pc);
  402.   
  403.   /* found valid frame setup - codestream now points to 
  404.    * start of push instructions for saving registers
  405.    */
  406.   
  407.   /* skip over register saves */
  408.   for (i = 0; i < 8; i++)
  409.     {
  410.       op = codestream_peek ();
  411.       /* break if not pushl inst */
  412.       if (op < 0x50 || op > 0x57) 
  413.     break;
  414.       codestream_get ();
  415.     }
  416.   
  417.   i386_follow_jump ();
  418.   
  419.   return (codestream_tell ());
  420. }
  421.  
  422. i386_push_dummy_frame ()
  423. {
  424.   CORE_ADDR sp = read_register (SP_REGNUM);
  425.   int regnum;
  426.   char regbuf[MAX_REGISTER_RAW_SIZE];
  427.   
  428.   sp = push_word (sp, read_register (PC_REGNUM));
  429.   sp = push_word (sp, read_register (FP_REGNUM));
  430.   write_register (FP_REGNUM, sp);
  431.   for (regnum = 0; regnum < NUM_REGS; regnum++)
  432.     {
  433.       read_register_gen (regnum, regbuf);
  434.       sp = push_bytes (sp, regbuf, REGISTER_RAW_SIZE (regnum));
  435.     }
  436.   write_register (SP_REGNUM, sp);
  437. }
  438.  
  439. i386_pop_frame ()
  440. {
  441.   FRAME frame = get_current_frame ();
  442.   CORE_ADDR fp;
  443.   int regnum;
  444.   struct frame_saved_regs fsr;
  445.   struct frame_info *fi;
  446.   char regbuf[MAX_REGISTER_RAW_SIZE];
  447.   
  448.   fi = get_frame_info (frame);
  449.   fp = fi->frame;
  450.   get_frame_saved_regs (fi, &fsr);
  451.   for (regnum = 0; regnum < NUM_REGS; regnum++) 
  452.     {
  453.       CORE_ADDR adr;
  454.       adr = fsr.regs[regnum];
  455.       if (adr)
  456.     {
  457.       read_memory (adr, regbuf, REGISTER_RAW_SIZE (regnum));
  458.       write_register_bytes (REGISTER_BYTE (regnum), regbuf,
  459.                 REGISTER_RAW_SIZE (regnum));
  460.     }
  461.     }
  462.   write_register (FP_REGNUM, read_memory_integer (fp, 4));
  463.   write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
  464.   write_register (SP_REGNUM, fp + 8);
  465.   flush_cached_frames ();
  466.   set_current_frame ( create_new_frame (read_register (FP_REGNUM),
  467.                     read_pc ()));
  468. }
  469.